/*
******************************************************************************************************* 
**  Copyright (C) 2019, 苏州检易生物科技有限公司 
**  All rights reserved. 
** 
**  FileName:       	work_task.c
**  Description:	
**  Author:        	 
**  Version				v0.1
**  Date:           	2019-05-09
**	Function List： 
**  History:         
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                              	调试开关
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                             INCLUDE FILES
*********************************************************************************************************
*/
#include "work_task.h"
#include "schedule_task.h"
#include "data_backup.h"
#include "crc16.h"
#include "app_msg.h"
#include "log_console.h"
#include "os_config.h"
#include "tcp_transfer.h"
#include "misc_task.h"
/*
*********************************************************************************************************
*                                              	宏定义
*********************************************************************************************************
*/
#define		WORK_TASK_STK_SIZE			1024
#define		WORK_TASK_MB_SIZE				32

/*
*********************************************************************************************************
*                                              	函数原型声明
*********************************************************************************************************
*/

static void work_task_init(void);
static void work_task_process(void *p_arg);
/*
*********************************************************************************************************
*                                              	全局变量定义
*********************************************************************************************************
*/
/*模块初始化静态变量*/
struct rt_thread   	rt_work_tcb;
struct rt_mailbox		rt_work_mb;
static char					work_task_stk[WORK_TASK_STK_SIZE];
static char					work_task_name[]="work task";
static char					work_task_mb_pool[WORK_TASK_MB_SIZE * 4];

//volatile uint8_t	sys_state = SYS_STATE_HW_INIT;

/*
*********************************************************************************************************
*                                              	模块静态变量定义
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                              	函数定义
*********************************************************************************************************
*/




/*
*********************************************************************************************************
*                                               本地函数声明
*********************************************************************************************************
*/

static void work_sys_state(uint32_t state);
static void sys_status_protocol_callback(protocol_cmd_t cmd,uint8_t * buff,uint16_t size);
//static void photon_backup_protocol_callback(protocol_cmd_t cmd,uint8_t * buff,uint16_t size);


/*
*********************************************************************************************************
*@brief:	仪器状态机				
*********************************************************************************************************
*/

void work_task_start(void)
{
	if(RT_EOK != rt_thread_init(&rt_work_tcb,
		work_task_name, 
		work_task_process,
		RT_NULL,
		work_task_stk,
		WORK_TASK_STK_SIZE,
		WORK_TASK_PRIO,
		RT_THREAD_TIME_SLICE))
	{
		Critical_Log("%s create failed!\r\n",work_task_name);
//		while(1){}
	}
	else
		rt_thread_startup(&rt_work_tcb);
	Trace_Log("%s created!\r\n",work_task_name);
}


/*
*********************************************************************************************************
*					
*********************************************************************************************************
*/


static void work_task_init(void)
{
	/*创建消息邮箱*/
	if(RT_EOK != rt_mb_init(&rt_work_mb,
		"work mailbox",
		work_task_mb_pool,
		WORK_TASK_MB_SIZE,
		RT_IPC_FLAG_FIFO
		))
	{
		Critical_Log("%s create failed!\r\n",work_task_name);
	}
	
	protocol_handler_register(CMD_SYSINIT,sys_status_protocol_callback);
	protocol_handler_register(CMD_START_TEST,sys_status_protocol_callback);
	protocol_handler_register(CMD_SUSPEND_TEST,sys_status_protocol_callback);
}

static void sys_status_protocol_callback(protocol_cmd_t cmd,uint8_t * buff,uint16_t size)
{
	switch(cmd)
	{
		case CMD_SUSPEND_TEST:
			app_msg_send(MSG_WORK_SYS_STATE, SYS_STATE_SUSPEND, &rt_work_mb);
		break;
		case CMD_SYSINIT:
			app_msg_send(MSG_WORK_SYS_STATE, SYS_STATE_MODULE_INIT, &rt_work_mb);
		break;
		case CMD_START_TEST:
			app_msg_send(MSG_WORK_SYS_STATE, SYS_STATE_WORK, &rt_work_mb);
		break;
		default:break;
	}
}
/*
*********************************************************************************************************
*					
*********************************************************************************************************
*/
static void work_task_process(void *p_arg)
{
	app_msg_t *p_msg = NULL;
	rt_err_t err;
	
	work_task_init();
	sys_para.sys_state = SYS_STATE_HW_INIT;
	Trace_Log("Now work task start!\n");

	while(1)
	{
		if(RT_EOK != rt_mb_recv(&rt_work_mb,(rt_uint32_t*)&p_msg,RT_WAITING_FOREVER)
			|| p_msg == NULL)
		{
			p_msg = NULL;
			continue;
		}
		
		switch(p_msg->event)
		{
			/* 系统状态切换 */
			case MSG_WORK_SYS_STATE:
				work_sys_state(p_msg->data);
				break;	
			default:
				break;
		}				
		
		app_msg_free(p_msg);
	}
}

static void work_sys_state(uint32_t state)
{
	uint32_t early_state = sys_para.sys_state;
	if(state == SYS_STATE_ERR)
	{
		Error_Log("Systate fatal err!\r\n");
		sys_para.sys_state = SYS_STATE_ERR;
		return;
	}
	rt_base_t it = rt_hw_interrupt_disable();
	switch(sys_para.sys_state)
	{
		case SYS_STATE_HW_INIT:
			if(state==SYS_STATE_HW_DONE)
#if PRODUCT_NAME_IVD_DEBUG 
				sys_para.sys_state = SYS_STATE_CALIB;
#else
				sys_para.sys_state = state;
#endif
			break;
		case SYS_STATE_HW_DONE:
			if(state==SYS_STATE_MODULE_INIT)
			{
				app_msg_send(MSG_SCHEDULE_SCH, ACT_SCHEDULE_INIT, &rt_schedule_mb);
				sys_para.sys_state = state;
				break;
			}
			break;
		case SYS_STATE_INIT_DONE:
			if(state==SYS_STATE_WORK)
			{
				app_msg_send(MSG_SCHEDULE_SCH, ACT_SCHEDULE_START_WORK, &rt_schedule_mb);
				sys_para.sys_state = state;
			}
			if(state==SYS_STATE_MODULE_INIT)
			{
				app_msg_send(MSG_SCHEDULE_SCH, ACT_SCHEDULE_INIT, &rt_schedule_mb);
				sys_para.sys_state = state;
				break;
			}
			if(state==SYS_STATE_CALIB)
			{
				sys_para.sys_state = state;
			}
			break;
		case SYS_STATE_MODULE_INIT:
			if(state == SYS_STATE_INIT_DONE)
			{
				sys_para.sys_state = state;
			}
			else if(state == SYS_STATE_WORK||state == SYS_STATE_MODULE_INIT)
			{
				for(uint8_t index = 0;index < MOTOR_NUM;index ++)
				{
					if(m_motor_list[index].status == MOTOR_STATE_STEP || 
						m_motor_list[index].status == MOTOR_STATE_HOMING)
						Trace_Log("Motor index %d unready!\r\n",m_motor_list[index].motor_id);
				}
			}
			break;
		case SYS_STATE_WORK:
			/*当前是流程状态 检查相关状态是否可以复位*/
		  if(schedule_check_init() && state == SYS_STATE_MODULE_INIT)
			{
				sys_para.sys_state = state;
				app_msg_send(MSG_SCHEDULE_SCH, ACT_SCHEDULE_INIT, &rt_schedule_mb);
			}
		  if(state == SYS_STATE_SUSPEND)
			{
				sys_para.sys_state = state;
			}
			break;
		case SYS_STATE_CALIB:
			/*当前是调试状态 检查相关状态位 是否可以复位*/
		  if(state == SYS_STATE_MODULE_INIT && schedule_check_init())
			{
				sys_para.sys_state = state;
				app_msg_send(MSG_SCHEDULE_SCH, ACT_SCHEDULE_INIT, &rt_schedule_mb);
			}
			break;
		case SYS_STATE_SUSPEND:
			/*当前是调试状态 检查相关状态位 是否可以复位*/
		  if(state == SYS_STATE_WORK)
			{
				sys_para.sys_state = state;
//				app_msg_send(MSG_SCHEDULE_SCH, ACT_SCHEDULE_INIT, &rt_schedule_mb);
			}
			break;
			default:break;
	}
	stdl_output_set(IO_TYPE_5VDC_OUT,LED_SYS_RED,STDL_IO_LOW);
	stdl_output_set(IO_TYPE_5VDC_OUT,LED_SYS_GREEN,STDL_IO_BLINK);
	switch(sys_para.sys_state)
	{
		case SYS_STATE_INIT_DONE:
		case SYS_STATE_WORK:
			stdl_output_set(IO_TYPE_5VDC_OUT,LED_SYS_RED,STDL_IO_LOW);
			stdl_output_set(IO_TYPE_5VDC_OUT,LED_SYS_GREEN,STDL_IO_HIGH);
			break;
		case SYS_STATE_ERR:
			stdl_output_set(IO_TYPE_5VDC_OUT,LED_SYS_RED,STDL_IO_BLINK);
			stdl_output_set(IO_TYPE_5VDC_OUT,LED_SYS_GREEN,STDL_IO_LOW);
			break;
		default:
			stdl_output_set(IO_TYPE_5VDC_OUT,LED_SYS_RED,STDL_IO_HIGH);
			stdl_output_set(IO_TYPE_5VDC_OUT,LED_SYS_GREEN,STDL_IO_LOW);
			break;
	}
	if(early_state != sys_para.sys_state)
	{
		system_period_upload();
	}
	rt_hw_interrupt_enable(it);
}


